<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <!-- Include the CesiumJS JavaScript and CSS files -->
    <script src="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Cesium.js"></script>
    <script src="/static/bytebuffer.min.js"></script>
    <script src="/static/cesiumTdt.js"></script>
    <link href="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
    <style>
        html, body, #cesiumContainer {
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
        }
    </style>
    <title>Cesium加载天地图三维地形、地名服务</title>
</head>

<body>
<div id="cesiumContainer"></div>
<script>
    const token = 'cec5eeadc16a3c964451ff083266df0c'
    const tdtUrl = 'https://t{s}.tianditu.gov.cn/';
    const subdomains = ['0', '1', '2', '3', '4', '5', '6', '7'];
    // 叠加影像服务
    const imgMap = new Cesium.UrlTemplateImageryProvider({
        url: tdtUrl + 'DataServer?T=img_w&x={x}&y={y}&l={z}&tk=' + token,
        subdomains: subdomains,
        tilingScheme: new Cesium.WebMercatorTilingScheme(),
        maximumLevel: 18,
        enablePickFeatures: false
    });

    // 叠加地形服务
    const terrainUrls = [];
    for (let i = 0; i < subdomains.length; i++) {
        const url = tdtUrl.replace('{s}', subdomains[i]) + 'mapservice/swdx?T=elv_c&tk=' + token;
        terrainUrls.push(url);
    }
    const provider = new Cesium.GeoTerrainProvider({
        urls: terrainUrls
    });

    // 初始化地球
    const viewer = new Cesium.Viewer('cesiumContainer', {
        infoBox: false,
        baseLayerPicker: false,
        terrain: new Cesium.Terrain(provider),
        baseLayer: new Cesium.ImageryLayer(imgMap),
        timeline: false,
        animation: false,
    })
    viewer._cesiumWidget._creditContainer.style.display = 'none'
    if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
        //判断是否支持图像渲染像素化处理
        viewer.resolutionScale = window.devicePixelRatio
    }
    viewer.scene.postProcessStages.fxaa.enabled = true


    // 叠加国界服务
    const iboMap = new Cesium.UrlTemplateImageryProvider({
        url: tdtUrl + 'DataServer?T=ibo_w&x={x}&y={y}&l={z}&tk=' + token,
        subdomains: subdomains,
        tilingScheme: new Cesium.WebMercatorTilingScheme(),
        maximumLevel: 18,
        enablePickFeatures: false
    });
    viewer.imageryLayers.addImageryProvider(iboMap);

    // 叠加三维地名服务
    const wtfs = new Cesium.GeoWTFS({
        viewer,
        subdomains: subdomains,
        metadata: {
            boundBox: {
                minX: -180,
                minY: -90,
                maxX: 180,
                maxY: 90
            },
            minLevel: 1,
            maxLevel: 20
        },
        aotuCollide: true, //是否开启避让
        collisionPadding: [5, 10, 8, 5], //开启避让时，标注碰撞增加内边距，上、右、下、左
        serverFirstStyle: true, //服务端样式优先
        labelGraphics: {
            font: "28px sans-serif",
            fontSize: 28,
            fillColor: Cesium.Color.WHITE,
            scale: 0.5,
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 5,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            showBackground: false,
            backgroundColor: Cesium.Color.RED,
            backgroundPadding: new Cesium.Cartesian2(10, 10),
            horizontalOrigin: Cesium.HorizontalOrigin.MIDDLE,
            verticalOrigin: Cesium.VerticalOrigin.TOP,
            eyeOffset: Cesium.Cartesian3.ZERO,
            pixelOffset: new Cesium.Cartesian2(0, 8)
        },
        billboardGraphics: {
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            verticalOrigin: Cesium.VerticalOrigin.CENTER,
            eyeOffset: Cesium.Cartesian3.ZERO,
            pixelOffset: Cesium.Cartesian2.ZERO,
            alignedAxis: Cesium.Cartesian3.ZERO,
            color: Cesium.Color.WHITE,
            rotation: 0,
            scale: 1,
            width: 18,
            height: 18
        }
    });
    //三维地名服务，使用wtfs服务
    wtfs.getTileUrl = function () {
        return tdtUrl + 'mapservice/GetTiles?lxys={z},{x},{y}&VERSION=1.0.0&tk=' + token;
    }
    wtfs.getIcoUrl = function () {
        return tdtUrl + 'mapservice/GetIcon?id={id}&tk=' + token;
    }
    wtfs.initTDT([{"x": 6, "y": 1, "level": 2, "boundBox": {"minX": 90, "minY": 0, "maxX": 135, "maxY": 45}}, {
        "x": 7,
        "y": 1,
        "level": 2,
        "boundBox": {"minX": 135, "minY": 0, "maxX": 180, "maxY": 45}
    }, {"x": 6, "y": 0, "level": 2, "boundBox": {"minX": 90, "minY": 45, "maxX": 135, "maxY": 90}}, {
        "x": 7,
        "y": 0,
        "level": 2,
        "boundBox": {"minX": 135, "minY": 45, "maxX": 180, "maxY": 90}
    }, {"x": 5, "y": 1, "level": 2, "boundBox": {"minX": 45, "minY": 0, "maxX": 90, "maxY": 45}}, {
        "x": 4,
        "y": 1,
        "level": 2,
        "boundBox": {"minX": 0, "minY": 0, "maxX": 45, "maxY": 45}
    }, {"x": 5, "y": 0, "level": 2, "boundBox": {"minX": 45, "minY": 45, "maxX": 90, "maxY": 90}}, {
        "x": 4,
        "y": 0,
        "level": 2,
        "boundBox": {"minX": 0, "minY": 45, "maxX": 45, "maxY": 90}
    }, {"x": 6, "y": 2, "level": 2, "boundBox": {"minX": 90, "minY": -45, "maxX": 135, "maxY": 0}}, {
        "x": 6,
        "y": 3,
        "level": 2,
        "boundBox": {"minX": 90, "minY": -90, "maxX": 135, "maxY": -45}
    }, {"x": 7, "y": 2, "level": 2, "boundBox": {"minX": 135, "minY": -45, "maxX": 180, "maxY": 0}}, {
        "x": 5,
        "y": 2,
        "level": 2,
        "boundBox": {"minX": 45, "minY": -45, "maxX": 90, "maxY": 0}
    }, {"x": 4, "y": 2, "level": 2, "boundBox": {"minX": 0, "minY": -45, "maxX": 45, "maxY": 0}}, {
        "x": 3,
        "y": 1,
        "level": 2,
        "boundBox": {"minX": -45, "minY": 0, "maxX": 0, "maxY": 45}
    }, {"x": 3, "y": 0, "level": 2, "boundBox": {"minX": -45, "minY": 45, "maxX": 0, "maxY": 90}}, {
        "x": 2,
        "y": 0,
        "level": 2,
        "boundBox": {"minX": -90, "minY": 45, "maxX": -45, "maxY": 90}
    }, {"x": 0, "y": 1, "level": 2, "boundBox": {"minX": -180, "minY": 0, "maxX": -135, "maxY": 45}}, {
        "x": 1,
        "y": 0,
        "level": 2,
        "boundBox": {"minX": -135, "minY": 45, "maxX": -90, "maxY": 90}
    }, {"x": 0, "y": 0, "level": 2, "boundBox": {"minX": -180, "minY": 45, "maxX": -135, "maxY": 90}}]);

    // 将三维球定位到中国
    viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(103.84, 31.15, 20000000),
        orientation: {
            heading: Cesium.Math.toRadians(348.4202942851978),
            pitch: Cesium.Math.toRadians(-89.74026687972041),
            roll: Cesium.Math.toRadians(0)
        },
        complete: function callback() {
            // 定位完成之后的回调函数
        }
    });
</script>
</body>

</html>